package com.zivwu.library.ui.base;


import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.chad.library.adapter.base.BaseQuickAdapter;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

public abstract class RecyclerFragment extends IFragment implements SwipeRefreshLayout.OnRefreshListener, BaseQuickAdapter.RequestLoadMoreListener {
    protected static final String ARGUMENT_NEED_REFRESH = "ARGUMENT_NEED_REFRESH";
    private boolean needSwipeRefreshLayout = false;
    private ViewGroup mRootView;
    private RecyclerView rvList;
    private SwipeRefreshLayout mSwipeRefreshLayout;
    private BaseQuickAdapter adapter;


    private int index = 1;
    private int pageSize = 20;


    @Override
    protected void initArguments(Bundle arguments) {
        needSwipeRefreshLayout = arguments.getBoolean(ARGUMENT_NEED_REFRESH, false);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        mRootView = initRootView();
        rvList = initRecyclerView();
        if (needSwipeRefreshLayout) {
            mSwipeRefreshLayout = initRefreshLayout();
            mSwipeRefreshLayout.addView(rvList);
            mRootView.addView(mSwipeRefreshLayout);
        } else {
            mRootView.addView(rvList);
        }

        return mRootView;
    }

    private SwipeRefreshLayout initRefreshLayout() {
        SwipeRefreshLayout layout = new SwipeRefreshLayout(mContext);
        layout.setLayoutParams(generateLayoutParams());
        layout.setOnRefreshListener(this);
        return layout;
    }

    private RecyclerView initRecyclerView() {
        RecyclerView recyclerView = new RecyclerView(mContext);
        recyclerView.setLayoutParams(generateLayoutParams());
        adapter = getAdapter();
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
        rvList.addItemDecoration(getItemDecoration());
        adapter.setOnLoadMoreListener(this, rvList);
        return recyclerView;
    }

    protected abstract BaseQuickAdapter getAdapter();


    protected
    @NonNull
    RecyclerView.ItemDecoration getItemDecoration() {
        return new DividerItemDecoration(
                mContext, DividerItemDecoration.VERTICAL);
    }


    private ViewGroup initRootView() {
        FrameLayout rootView = new FrameLayout(mContext);
        rootView.setLayoutParams(generateLayoutParams());
        return rootView;
    }


    private FrameLayout.LayoutParams generateLayoutParams() {
        return new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
    }


    protected abstract
    @LayoutRes
    int getEmptyView();

    protected abstract
    @LayoutRes
    int getLoadingView();

    protected abstract
    @LayoutRes
    int getFailView();

    @Override
    public void onRefresh() {
        index = 1;
        adapter.setEmptyView(getLoadingView());
        adapter.setNewData(null);
        onLoadMoreRequested();
    }

    @Override
    public void onLoadMoreRequested() {
        getData()
                .subscribe(new Subscriber());
    }


    protected void showFail(String msg) {
        shadowSwipeRefreshLayout();
        if (adapter.getData().size() != 0) {
            adapter.loadMoreFail();
        } else {
            adapter.setEmptyView(getFailView());
        }

    }

    protected void showComplete() {
        adapter.setEmptyView(getEmptyView());
        shadowSwipeRefreshLayout();
        adapter.loadMoreComplete();
    }

    protected void showEnd() {
        adapter.setEmptyView(getEmptyView());
        shadowSwipeRefreshLayout();
        adapter.loadMoreEnd();

    }

    private void shadowSwipeRefreshLayout() {
        if (needSwipeRefreshLayout)
            mSwipeRefreshLayout.setRefreshing(false);

    }


    protected abstract <T> Observable<T> getData();


    private class Subscriber<T> implements Observer<List<T>> {

        @Override
        public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {

        }

        @Override
        public void onNext(@io.reactivex.annotations.NonNull List<T> t) {
            if (index == 1) {
                adapter.setNewData(null);
            }
            adapter.addData(t);
            if (t.size() < pageSize) {
                showEnd();
            } else {
                showComplete();
            }
        }

        @Override
        public void onError(@io.reactivex.annotations.NonNull Throwable e) {
            showFail(e.getMessage());
        }

        @Override
        public void onComplete() {
            index++;
        }
    }


}
